From 14dc44913037f6e2ba9a2871addd3d4a49498797 Mon Sep 17 00:00:00 2001 From: Steven Smith Date: Fri, 1 Dec 2006 12:03:15 +0000 Subject: [PATCH] [PVFB] Make sure that framebuffer backend goes away when the domain terminates, and that it cleans up its area of xenstore. Tidy up argument parsing a little while I'm here. Signed-off-by: Steven Smith --- tools/xenfb/sdlfb.c | 10 +++++++++- tools/xenfb/vncfb.c | 10 +++++++++- tools/xenfb/xenfb.c | 27 ++++++++++++++++++++++++--- tools/xenfb/xenfb.h | 1 + 4 files changed, 43 insertions(+), 5 deletions(-) diff --git a/tools/xenfb/sdlfb.c b/tools/xenfb/sdlfb.c index cc5f8d6f52..6276c34659 100644 --- a/tools/xenfb/sdlfb.c +++ b/tools/xenfb/sdlfb.c @@ -204,6 +204,7 @@ static int sdl_on_event(struct xenfb *xenfb, SDL_Event *event) static struct option options[] = { { "domid", 1, NULL, 'd' }, { "title", 1, NULL, 't' }, + { NULL } }; int main(int argc, char **argv) @@ -220,6 +221,7 @@ int main(int argc, char **argv) int do_quit = 0; int opt; char *endp; + int retval; while ((opt = getopt_long(argc, argv, "d:t:", options, NULL)) != -1) { @@ -234,6 +236,8 @@ int main(int argc, char **argv) case 't': title = strdup(optarg); break; + case '?': + exit(1); } } if (optind != argc) { @@ -323,7 +327,11 @@ int main(int argc, char **argv) if (do_quit) break; - xenfb_poll(xenfb, &readfds); + retval = xenfb_poll(xenfb, &readfds); + if (retval == -2) + xenfb_teardown(xenfb); + if (retval < 0) + break; } xenfb_delete(xenfb); diff --git a/tools/xenfb/vncfb.c b/tools/xenfb/vncfb.c index 2fc970e0cc..49fc730625 100644 --- a/tools/xenfb/vncfb.c +++ b/tools/xenfb/vncfb.c @@ -253,6 +253,7 @@ static struct option options[] = { { "title", 1, NULL, 't' }, { "unused", 0, NULL, 'u' }, { "listen", 1, NULL, 'l' }, + { NULL } }; int main(int argc, char **argv) @@ -272,6 +273,7 @@ int main(int argc, char **argv) int nfds; char portstr[10]; char *endp; + int r; while ((opt = getopt_long(argc, argv, "d:p:t:u", options, NULL)) != -1) { @@ -301,6 +303,8 @@ int main(int argc, char **argv) case 'l': listen = strdup(optarg); break; + case '?': + exit(1); } } if (optind != argc) { @@ -383,7 +387,11 @@ int main(int argc, char **argv) break; } - xenfb_poll(xenfb, &readfds); + r = xenfb_poll(xenfb, &readfds); + if (r == -2) + xenfb_teardown(xenfb); + if (r < 0) + break; } rfbScreenCleanup(server); diff --git a/tools/xenfb/xenfb.c b/tools/xenfb/xenfb.c index 82d31772df..496a365079 100644 --- a/tools/xenfb/xenfb.c +++ b/tools/xenfb/xenfb.c @@ -187,6 +187,17 @@ struct xenfb *xenfb_new(void) return NULL; } +/* Remove the backend area in xenbus since the framebuffer really is + going away. */ +void xenfb_teardown(struct xenfb *xenfb_pub) +{ + struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub; + + xs_rm(xenfb->xsh, XBT_NULL, xenfb->fb.nodename); + xs_rm(xenfb->xsh, XBT_NULL, xenfb->kbd.nodename); +} + + void xenfb_delete(struct xenfb *xenfb_pub) { struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub; @@ -564,7 +575,7 @@ static void xenfb_on_kbd_event(struct xenfb_private *xenfb) xc_evtchn_notify(xenfb->evt_xch, xenfb->kbd.port); } -static void xenfb_on_state_change(struct xenfb_device *dev) +static int xenfb_on_state_change(struct xenfb_device *dev) { enum xenbus_state state; @@ -572,6 +583,10 @@ static void xenfb_on_state_change(struct xenfb_device *dev) switch (state) { case XenbusStateUnknown: + /* There was an error reading the frontend state. The + domain has probably gone away; in any case, there's + not much point in us continuing. */ + return -1; case XenbusStateInitialising: case XenbusStateInitWait: case XenbusStateInitialised: @@ -585,14 +600,17 @@ static void xenfb_on_state_change(struct xenfb_device *dev) xs_unwatch(dev->xenfb->xsh, dev->otherend, ""); xenfb_switch_state(dev, state); } + return 0; } +/* Returns 0 normally, -1 on error, or -2 if the domain went away. */ int xenfb_poll(struct xenfb *xenfb_pub, fd_set *readfds) { struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub; evtchn_port_t port; unsigned dummy; char **vec; + int r; if (FD_ISSET(xc_evtchn_fd(xenfb->evt_xch), readfds)) { port = xc_evtchn_pending(xenfb->evt_xch); @@ -611,8 +629,11 @@ int xenfb_poll(struct xenfb *xenfb_pub, fd_set *readfds) if (FD_ISSET(xs_fileno(xenfb->xsh), readfds)) { vec = xs_read_watch(xenfb->xsh, &dummy); free(vec); - xenfb_on_state_change(&xenfb->fb); - xenfb_on_state_change(&xenfb->kbd); + r = xenfb_on_state_change(&xenfb->fb); + if (r == 0) + r = xenfb_on_state_change(&xenfb->kbd); + if (r == -1) + return -2; } return 0; diff --git a/tools/xenfb/xenfb.h b/tools/xenfb/xenfb.h index 007eb3b9b4..c08d979b39 100644 --- a/tools/xenfb/xenfb.h +++ b/tools/xenfb/xenfb.h @@ -21,6 +21,7 @@ struct xenfb struct xenfb *xenfb_new(void); void xenfb_delete(struct xenfb *xenfb); +void xenfb_teardown(struct xenfb *xenfb); int xenfb_attach_dom(struct xenfb *xenfb, int domid); -- 2.30.2